﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MM.Toolkit.Tester
{
    public class MainPageModel : DependencyObject, INotifyPropertyChanged
    {
        #region -: Properties :-

        private CarService carsvc = null;

        #endregion

        #region -: Properties :-

        public DateTime? TestDate
        {
            get { return (DateTime?)GetValue(TestDateProperty); }
            set
            {
                SetValue(TestDateProperty, value);
                NotifyPropertyChanged("TestDate");
            }
        }

        public Boolean DateButtonIsVisible
        {
            get { return (Boolean)GetValue(DateButtonIsVisibleProperty); }
            set
            {
                SetValue(DateButtonIsVisibleProperty, value);
                NotifyPropertyChanged("DateButtonIsVisible");
            }
        }

        public Boolean TimeButtonIsVisible
        {
            get { return (Boolean)GetValue(TimeButtonIsVisibleProperty); }
            set
            {
                SetValue(TimeButtonIsVisibleProperty, value);
                NotifyPropertyChanged("TimeButtonIsVisible");
            }
        }

        public Boolean UpDownButtonsIsVisible
        {
            get { return (Boolean)GetValue(UpDownButtonsIsVisibleProperty); }
            set
            {
                SetValue(UpDownButtonsIsVisibleProperty, value);
                NotifyPropertyChanged("UpDownButtonsIsVisible");
            }
        }

        public String DateFormat
        {
            get { return (String)GetValue(DateFormatProperty); }
            set
            {
                SetValue(DateFormatProperty, value);
                NotifyPropertyChanged("DateFormat");
            }
        }

        public String SearchText
        {
            get { return (String)GetValue(SearchTextProperty); }
            set
            {
                SetValue(SearchTextProperty, value);
                NotifyPropertyChanged("SearchText");
            }
        }

        public ObservableCollection<Car> SearchItems
        {
            get { return (ObservableCollection<Car>)GetValue(SearchItemsProperty); }
            set
            {
                SetValue(SearchItemsProperty, value);
                NotifyPropertyChanged("SearchItems");
            }
        }

        public Car SelectedSearchItem
        {
            get { return (Car)GetValue(SelectedSearchItemProperty); }
            set
            {
                SetValue(SelectedSearchItemProperty, value);
                NotifyPropertyChanged("SelectedSearchItem");
            }
        }

        public DelegateCommand SearchStartedCommand
        {
            get { return (DelegateCommand)GetValue(SearchStartedCommandProperty); }
            set
            {
                SetValue(SearchStartedCommandProperty, value);
                NotifyPropertyChanged("SearchStartedCommand");
            }
        }

        public DelegateCommand SearchCompletedCommand
        {
            get { return (DelegateCommand)GetValue(SearchCompletedCommandProperty); }
            set
            {
                SetValue(SearchCompletedCommandProperty, value);
                NotifyPropertyChanged("SearchCompletedCommand");
            }
        }

        #endregion

        #region -: Dependency Properties :-

        public static readonly DependencyProperty TestDateProperty = DependencyProperty.Register("TestDate", typeof(DateTime?), typeof(MainPageModel), new PropertyMetadata(null));
        public static readonly DependencyProperty DateButtonIsVisibleProperty = DependencyProperty.Register("DateButtonIsVisible", typeof(Boolean), typeof(MainPageModel), new PropertyMetadata(true));
        public static readonly DependencyProperty TimeButtonIsVisibleProperty = DependencyProperty.Register("TimeButtonIsVisible", typeof(Boolean), typeof(MainPageModel), new PropertyMetadata(true));
        public static readonly DependencyProperty UpDownButtonsIsVisibleProperty = DependencyProperty.Register("UpDownButtonsIsVisible", typeof(Boolean), typeof(MainPageModel), new PropertyMetadata(true));
        public static readonly DependencyProperty DateFormatProperty = DependencyProperty.Register("DateFormat", typeof(String), typeof(MainPageModel), new PropertyMetadata(null));
        public static readonly DependencyProperty SearchTextProperty = DependencyProperty.Register("SearchText", typeof(String), typeof(MainPageModel), new PropertyMetadata(null));
        public static readonly DependencyProperty SearchItemsProperty = DependencyProperty.Register("SearchItems", typeof(ObservableCollection<Car>), typeof(MainPageModel), new PropertyMetadata(null));
        public static readonly DependencyProperty SelectedSearchItemProperty = DependencyProperty.Register("SelectedSearchItem", typeof(Car), typeof(MainPageModel), new PropertyMetadata(null));
        public static readonly DependencyProperty SearchStartedCommandProperty = DependencyProperty.Register("SearchStartedCommand", typeof(DelegateCommand), typeof(MainPageModel), new PropertyMetadata(null));
        public static readonly DependencyProperty SearchCompletedCommandProperty = DependencyProperty.Register("SearchCompletedCommand", typeof(DelegateCommand), typeof(MainPageModel), new PropertyMetadata(null));

        #endregion

        #region -: Constructors & Destructor :-

        public MainPageModel()
        {
            carsvc = new CarService();
            carsvc.GetCarsCompleted += carsvc_GetCarsCompleted;

            this.TestDate = DateTime.Now;
            this.SearchItems = new ObservableCollection<Car>();
            this.SearchStartedCommand = DelegateCommand.Create(doSearchStarted, canSearchStartedExecute);
        }

        #endregion

        #region -: CarService Events :-

        private void carsvc_GetCarsCompleted(object sender, GetCarsCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                foreach (Car car in e.Result)
                    this.SearchItems.Add(car);
            }
            else
                MessageBox.Show("Unable to get cars!\r\n\r\nError :\r\n" + e.Error.Message);

            // Notifying the SearchBox control that the search is done
            if (this.SearchCompletedCommand != null)
                this.SearchCompletedCommand.Execute(null);
        }

        #endregion

        #region -: Private Methods :-

        private Boolean canSearchStartedExecute()
        {
            return true;
        }
        private void doSearchStarted()
        {
            this.SearchItems.Clear();
            carsvc.GetCarsAsync(this.SearchText);
        }

        #endregion

        #region -: INotifyPropertyChanged Members :-

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String aPropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(aPropertyName));
        }

        #endregion
    }
}
